package com.iqiyi.pps.epg.core.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iqiyi.kiwi.utils.Configuration;
import com.iqiyi.pps.epg.core.infrastructure.mail.MailService;
import com.iqiyi.pps.epg.core.model.channel.ChannelConfig;
import com.iqiyi.pps.epg.core.model.channel.ChannelLog;
import com.iqiyi.pps.epg.core.model.common.MailHeader;
import com.iqiyi.pps.epg.core.model.stream.LiveChannelStream;
import com.iqiyi.pps.epg.core.model.stream.LiveStream;
import com.iqiyi.pps.epg.core.rpc.qipu.impl.QipuManager;
import com.iqiyi.pps.epg.core.rpc.stream.LiveStreamWebServiceImpl;
import com.iqiyi.pps.epg.core.service.channel.ChannelService;
import com.iqiyi.pps.epg.core.service.channel.ChannelServiceImpl;
import com.iqiyi.pps.epg.core.service.stream.LiveChannelStreamService;
import com.iqiyi.pps.epg.core.service.stream.LiveChannelStreamServiceImpl;
import com.iqiyi.pps.epg.core.service.stream.LiveStreamService;
import org.apache.commons.lang3.StringUtils;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2015/2/13.
 */
public class LiveStreamManager {

    private static final Logger logger = LoggerFactory.getLogger(LiveStreamManager.class);

    private static final boolean EMAIL_SWITCH = Boolean.getBoolean(Configuration.getString("email.rtmp.switch", "false"));

    public static final String P2P_OFFLINE_REPEAT = "p2pchannel offline repeat";

//    private boolean EMAIL_LOCK_KEY = Configuration.getString("");

    public static boolean isProductionEnv() {
        return "production".equals(Configuration.getString("deploy.env"));
    }

    public static JSONObject createFlv(String streamIp, String streamName, String peerCount, String bcsNum, String cutterId, int sliceDelay,
                                       int userCount, String resolution, int apiVersion, String streamUrls, int playType) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER, "addchannel");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("fms_host", streamIp);
        params.put("stream_name", streamName);
        params.put("channel_name", streamName);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("channel_offset", "-5");
        params.put("channel_piece_size", "10");
        params.put("end_datetime", "");
        params.put("login", "");

        if (!cutterId.equals("0")) {
            params.put("cutter_id", "c" + cutterId);
        }

        params.put("bcs_num", bcsNum);

        params.put("send_hcdn", "yes");
        params.put("mir_num", peerCount);
        params.put("slice_delay", sliceDelay + "");
        params.put("user_count", userCount + "");
        params.put("resolution", resolution);
        params.put("version", LiveChannelStream.STREAM_API_VERSION_MAP.get(apiVersion));
        params.put("stream_app", "live");

        if (StringUtils.isNotBlank(streamUrls)) {
            params.put("stream_url", streamUrls);
        }
        params.put("play_type", playType);
        JSONObject jsonObject = ApiHttpRequestUtil.postMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject startFlv(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER, "startchannel");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject stopFlv(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER, "stopchannel");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject deleteFlv(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER, "delchannel");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject restartFlv(String url, String newStreamIp, String streamName, int apiVersion,
                                        String streamUrls) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER, "restartchannel");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("rtmp_server", newStreamIp);
        params.put("stream_name", streamName);
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.STREAM_API_VERSION_MAP.get(apiVersion));

        if (StringUtils.isNotBlank(streamUrls)) {
            params.put("stream_url", streamUrls);
        }
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject createTs(String streamIp, String streamName, String cutterId, int sliceDelay, int apiVersion,
                                      String streamUrls) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER8, "addm3u8_ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("in_fms_host", streamIp);
        params.put("in_stream_name", streamName);
        params.put("channel_name", streamName);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        if (!cutterId.equals("0")) {
            params.put("cutter_id", "c" + cutterId);
        }
        params.put("slice_delay", sliceDelay + "");
        params.put("version", LiveChannelStream.TS_STREAM_API_VERSION_MAP.get(apiVersion));
        params.put("stream_app", "live");

        if (StringUtils.isNotBlank(streamUrls)) {
            params.put("stream_url", streamUrls);
        }
        JSONObject jsonObject = ApiHttpRequestUtil.postMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject startTs(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER8, "startm3u8_ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.TS_STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject stopTs(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER8, "endm3u8_ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.TS_STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject deleteTs(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER8, "delm3u8_ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.TS_STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject restartTs(String url, String newStreamIp, String streamName, int apiVersion, String streamUrls) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_CUTTER8, "restartm3u8_ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("rtmp_server", newStreamIp);
        params.put("stream_name", streamName);
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.TS_STREAM_API_VERSION_MAP.get(apiVersion));

        if (StringUtils.isNotBlank(streamUrls)) {
            params.put("stream_url", streamUrls);
        }
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject createDolby(String streamUrl, String streamName, String cutterId, int sliceDelay, int userCount,
                                         String resolution, int apiVersion, String streamUrls) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_DOLBY, "addhttp2ts");
        Map<String, Object> params = new HashMap<>();
        params.put("stream_url", streamUrl);
        params.put("channel_name", streamName);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        if (!cutterId.equals("0")) {
            params.put("cutter_id", "c" + cutterId);
        }
        params.put("send_hcdn", "yes");
        params.put("slice_delay", sliceDelay + "");
        params.put("user_count", userCount + "");
        params.put("resolution", resolution);
        params.put("version", LiveChannelStream.DOLBY_STREAM_API_VERSION_MAP.get(apiVersion));

        if (StringUtils.isNotBlank(streamUrls)) {
            params.put("stream_url", streamUrls);
        }
        JSONObject jsonObject = ApiHttpRequestUtil.postMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject startDolby(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_DOLBY, "starthttp2ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.DOLBY_STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject stopDolby(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_DOLBY, "stophttp2ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.DOLBY_STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject restartDolby(String url, String streamUrl, int apiVersion, String streamUrls) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_DOLBY, "restarthttp2ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.DOLBY_STREAM_API_VERSION_MAP.get(apiVersion));

        if (StringUtils.isNotBlank(streamUrls)) {
            params.put("stream_url", streamUrls);
        } else {
            if (StringUtils.isNotEmpty(streamUrl)) {
                params.put("stream_url", streamUrl);
            }
        }

        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject deleteDolby(String url, int apiVersion) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_DOLBY, "delhttp2ts");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("ch", url);
        params.put("user", "ppslive");
        params.put("src_type", "PPC");
        params.put("version", LiveChannelStream.TS_STREAM_API_VERSION_MAP.get(apiVersion));
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject p2pOnline(String streamIp, String liveChannelSteamId, String streamName, String peerCount) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_P2P, "accept.php");
        JSONObject content = new JSONObject();
        content.put("channel_id", liveChannelSteamId);
        content.put("channel_name", streamName);
        content.put("source_ip", streamIp);
        content.put("genera", "ws");
        content.put("comment", streamName);
        content.put("peer_count", peerCount);
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("content", content);
        jsonParam.put("head", "p2pchannelonline");

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("msg", jsonParam.toJSONString());
        JSONObject jsonObject = ApiHttpRequestUtil.getMethod(httpUrl, params);
        return jsonObject;
    }

    public static JSONObject p2pOffline(String liveChannelSteamId) {
        String httpUrl = String.format(OuterApiUtil.BASE_URL_P2P, "accept.php");
        JSONObject content = new JSONObject();
        content.put("channel_id", liveChannelSteamId);
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("head", "p2pchanneloffline");
        jsonParam.put("content", content);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("msg", jsonParam.toJSONString());
        JSONObject jsonObject = ApiHttpRequestUtil.postMethod(httpUrl, params);
        return jsonObject;
    }

    // 删除流
    public static void deleteStream(LiveStream liveStream, Long liveChannelStreamId, int streamApiVersion) {
        if (LiveStream.FORMATTYPE_FLV.equals(liveStream.getFormatType())) {
            JSONObject jsonObject = deleteFlv(liveStream.getUrl(), streamApiVersion);
            if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {      //HTTP返回成功
                logger.info("[LiveStreamManager][deleteFlv][SUCCESS][URL:{}]", liveStream.getUrl());
            } else {
                logger.info("[LiveStreamManager][deleteFlv][FAIL][URL:{}]", liveStream.getUrl());
            }
        } else if (LiveStream.FORMATTYPE_P2P.equals(liveStream.getFormatType())) {
            JSONObject jsonObject = p2pOffline(liveChannelStreamId + "");
            if (jsonObject != null && jsonObject.getJSONObject("content").getInteger("code") == 0) {   //HTTP返回成功
                logger.info("[LiveStreamManager][p2pOffline][SUCCESS][liveChannelStreamId:{}]", liveChannelStreamId);
            } else {
                logger.info("[LiveStreamManager][p2pOffline][FAIL][liveChannelStreamId:{}]", liveChannelStreamId);
            }
        } else if (LiveStream.FORMATTYPE_TS.equals(liveStream.getFormatType())) {
            if (StringUtils.isEmpty(liveStream.getDolby_ch())) {
                JSONObject jsonObject = deleteTs(liveStream.getUrl(), streamApiVersion);
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {           //HTTP返回成功
                    logger.info("[LiveStreamManager][deleteTs][SUCCESS][URL:{}]", liveStream.getUrl());
                } else {
                    logger.info("[LiveStreamManager][deleteTs][FAIL][URL:{}]", liveStream.getUrl());
                }
            } else {
                JSONObject jsonObject = deleteDolby(liveStream.getDolby_ch(), streamApiVersion);
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {           //HTTP返回成功
                    logger.info("[LiveStreamManager][deleteNewTs][SUCCESS][URL:{}]", liveStream.getDolby_ch());
                } else {
                    logger.info("[LiveStreamManager][deleteNewTs][FAIL][URL:{}]", liveStream.getDolby_ch());
                }

            }
        } else if (LiveStream.FORMATTYPE_DOLBY.equals(liveStream.getFormatType())) {
            JSONObject jsonObject = deleteDolby(liveStream.getDolby_ch(), streamApiVersion);
            if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {           //HTTP返回成功
                logger.info("[LiveStreamManager][deleteDolby][SUCCESS][URL:{}]", liveStream.getDolby_ch());
            } else {
                logger.info("[LiveStreamManager][deleteDolby][FAIL][URL:{}]", liveStream.getDolby_ch());
            }
        }
    }

    public static String rtmpChanged(LiveChannelStream liveChannelStream, String newStreamIp) {
        String code = null;
        if (liveChannelStream == null || StringUtils.isEmpty(newStreamIp)) {
            logger.info("[LiveStreamManager][rtmpChanged][liveChannelStream = {}][newStreamIp = {}]", liveChannelStream, newStreamIp);
            return code;
        }

        Long fatherId = liveChannelStream.getFatherId();
        String streamName = liveChannelStream.getStreamName();
        String oldStreamIp = liveChannelStream.getStreamIp();

        ChannelService service = (ChannelService) ApplicationContextUtil.getBean(ChannelService.class);

        try {
            LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);

            logger.info("[rtmpChanged][liveChannelStream={}][newStreamIp={}][start]", JSON.toJSONString(liveChannelStream), newStreamIp);

            liveChannelStream.setStreamIp(newStreamIp);
            liveChannelStreamService.save(liveChannelStream);

            liveChannelStreamService.updateStreamUrlsBackup(liveChannelStream, true, liveChannelStream.getBackupEachOther() == 1);

            logger.info("[rtmpChanged][liveChannelStream={}][newStreamIp={}][end]", JSON.toJSONString(liveChannelStream), newStreamIp);

//            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamServiceImpl.class);
//            List<LiveStream> liveStreams = liveStreamService.get(fatherId, streamName);
//            logger.info("[LiveStreamManager][rtmpChanged][liveStreams][fatherId={}][streamName={}][size={}]", new Object[]{fatherId, streamName, liveStreams == null ? 0 : liveStreams.size()});
//            for (LiveStream liveStream : liveStreams) {
//                if (liveStream.getStatus() == LiveStream.STATUS_START) {
//                    JSONObject descr = new JSONObject();
//                    descr.put("oldStreamIp", oldStreamIp);
//                    descr.put("newStreamIp", newStreamIp);
//
//                    if (LiveStream.FORMATTYPE_FLV.equals(liveStream.getFormatType())) {
//                        //记录操作日志
//                        ChannelLog channelLog = new ChannelLog();
//                        channelLog.setFatherId(fatherId);
//                        channelLog.setUser("_system_");
//                        channelLog.setType(214);
//                        JSONObject jsonObject = LiveStreamManager.restartFlv(liveStream.getUrl(), newStreamIp, streamName, liveChannelStream.getStreamApiVersion(), liveChannelStream.getStreamUrls());
//                        logger.info("[restartFlv][response = {}]", jsonObject.toJSONString());
//                        if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {  //HTTP返回成功
//                            JSONObject data = jsonObject.getJSONObject("data");
//                            String url = data.getString("ch");
//                            if (!liveStream.getUrl().equals(url)) {
//                                logger.info("[restartFlv][liveStream.getUrl() = {}][httpUrl = {}]", liveStream.getUrl(), url);
//                                code = Constants.CODE_INFO_STREAM_CREATE_REPEAT;
//                                descr.put("code", code);
//                                channelLog.setDescr(descr.toJSONString());
//                                service.saveLog(channelLog);
//                                return code;
//                            } else {
//                                code = Constants.CODE_SUC;
//                                descr.put("code", Constants.CODE_SUC);
//                                channelLog.setDescr(descr.toJSONString());
//                                service.saveLog(channelLog);
//                            }
//                        } else {
//                            logger.info("[restartFlv][Http][error][message={}]", jsonObject.getString("message"));
//                            code = Constants.CODE_INFO_STREAM_CREATE_REPEAT;
//                            descr.put("code", code);
//                            descr.put("message", jsonObject.getString("message"));
//                            channelLog.setDescr(descr.toJSONString());
//                            service.saveLog(channelLog);
//                            return code;
//                        }
//                    } else if (LiveStream.FORMATTYPE_TS.equals(liveStream.getFormatType())) {
//                        //记录操作日志
//                        ChannelLog channelLog = new ChannelLog();
//                        channelLog.setFatherId(fatherId);
//                        channelLog.setUser("_system_");
//                        channelLog.setType(224);
//                        JSONObject jsonObject = LiveStreamManager.restartTs(liveStream.getUrl(), newStreamIp, liveStream.getStreamName(), liveChannelStream.getStreamApiVersion(),
//                                liveChannelStream.getStreamUrls());
//                        logger.info("[restartTs][response = {}]", jsonObject.toJSONString());
//                        if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {          //HTTP返回成功
//                            JSONObject data = jsonObject.getJSONObject("data");
//                            String url = data.getString("ch");
//                            if (!liveStream.getUrl().equals(url)) {
//                                logger.info("[restartTs][liveStream.getUrl() = {}][httpUrl = {}]", liveStream.getUrl(), url);
//                                code = Constants.CODE_INFO_STREAM_CREATE_REPEAT;
//                                descr.put("code", code);
//                                channelLog.setDescr(descr.toJSONString());
//                                service.saveLog(channelLog);
//                                return code;
//                            } else {
//                                code = Constants.CODE_SUC;
//                                descr.put("code", Constants.CODE_SUC);
//                                channelLog.setDescr(descr.toJSONString());
//                                service.saveLog(channelLog);
//                            }
//                        } else {
//                            logger.info("[restartTs][Http][error][message={}]", jsonObject.getString("message"));
//                            code = Constants.CODE_INFO_STREAM_CREATE_REPEAT;
//                            descr.put("code", code);
//                            descr.put("message", jsonObject.getString("message"));
//                            channelLog.setDescr(descr.toJSONString());
//                            service.saveLog(channelLog);
//                            return code;
//                        }
//                    }
//                }
//            }
//            logger.info("[LiveStreamManager][rtmpChanged][for][code={}]", code);
        } catch (Exception e) {
            logger.error("[LiveStreamManager][rtmpChanged]", e);
            return null;
        } finally {
            //报警邮件
            logger.info("[LiveStreamManager][rtmpChanged][email][switch = {}]", EMAIL_SWITCH);
            if (EMAIL_SWITCH) {
                try {
                    if (!Constants.CODE_SUC.equals(code)) {
                        List<ChannelConfig> mailList = service.getConfig(ChannelConfig.TEAM_TRIGGER_MAIL_LIST);
                        if (mailList != null) {
                            MailService mailservice = (MailService) ApplicationContextUtil.getBean(MailService.class);
                            MailHeader mailHeader = new MailHeader();
                            String[] tos = new String[mailList.size()];
                            int i = 0;
                            for (ChannelConfig item : mailList) {
                                tos[i] = item.getVal();
                                ++i;
                            }
                            mailHeader.setTos(tos);
                            mailHeader.setTitle("[EPG自动报警]直播流重启失败");
                            StringBuffer mailContent = new StringBuffer();
                            if (liveChannelStream != null) {
                                mailContent.append("频道ID: ").append(fatherId).append("<br/>")
                                        .append("流名称: ").append(streamName).append("<br/>")
                                        .append("老Rtmp地址: ").append(oldStreamIp).append("<br/>")
                                        .append("新Rtmp地址: ").append(newStreamIp).append("<br/>")
                                        .append("CODE: ").append(code).append("<br/>");
                            } else {
                                mailContent.append("liveChannelStream参数为null,newStreamIp=" + newStreamIp);
                            }
                            boolean flag = mailservice.sendMail(mailHeader, 0L, mailContent.toString());
                            logger.info("[LiveStreamManager][rtmpChanged][email][flag = {}]:", flag);
                        }
                    }
                } catch (Exception e) {
                    logger.error("[LiveStreamManager][rtmpChanged][finally]", e);
                }
            }
        }
        return code;
    }

    public static String flv(long fatherId, String streamName, String isDefault, String streamIp) {
        LiveStreamWebServiceImpl liveStreamWebService = (LiveStreamWebServiceImpl) ApplicationContextUtil.getBean(LiveStreamWebServiceImpl.class);
        try {
            liveStreamWebService.deleteFlv(fatherId, streamName);
            String result = liveStreamWebService.createFlv(fatherId, streamName, isDefault, streamIp);
            String streamAppendInfo= "[streamName=" + streamName + "][streamIp=" + streamIp + "]";
            writeChannelLog(fatherId, 210, result.equals(Constants.CODE_SUC) ? "创建成功"+streamAppendInfo : "创建失败"+streamAppendInfo);

            String code = liveStreamWebService.startFlv(fatherId, streamName);
            writeChannelLog(fatherId, 211, result.equals(Constants.CODE_SUC) ? "启动成功"+streamAppendInfo : "启动失败"+streamAppendInfo);
            //记录操作日志
            return code;
        } catch (TException e) {
            logger.error("AutoFlv error", e);
        } catch (Exception e) {
            logger.error("AutoFlv error", e);
        }
        return Constants.CODE_ERROR;
    }

    public static String ts(long fatherId, String streamName, String streamIp) {
        LiveStreamWebServiceImpl liveStreamWebService = (LiveStreamWebServiceImpl) ApplicationContextUtil.getBean(LiveStreamWebServiceImpl.class);
        try {
            liveStreamWebService.deleteTs(fatherId, streamName);
            String result = liveStreamWebService.createTs(fatherId, streamName, streamIp);
            String streamAppendInfo= "[streamName=" + streamName + "][streamIp=" + streamIp + "]";
            writeChannelLog(fatherId, 220, result.equals(Constants.CODE_SUC) ? "创建成功"+streamAppendInfo : "创建失败"+streamAppendInfo);
            String code = liveStreamWebService.startTs(fatherId, streamName);
            writeChannelLog(fatherId, 221, result.equals(Constants.CODE_SUC) ? "启动成功"+streamAppendInfo : "启动失败"+streamAppendInfo);
            return code;
        } catch (TException e) {
            logger.error("AutoTs error", e);
        } catch (Exception e) {
            logger.error("AutoTs error", e);
        }
        return Constants.CODE_ERROR;
    }

    public static String dolby(long fatherId, String streamName) {
        LiveStreamWebServiceImpl liveStreamWebService = (LiveStreamWebServiceImpl) ApplicationContextUtil.getBean(LiveStreamWebServiceImpl.class);

        try {
            liveStreamWebService.deleteDolby(fatherId, streamName);
            String result = liveStreamWebService.createDolby(fatherId, streamName);
            String streamAppendInfo= "[streamName=" + streamName + "][fatherId=" + fatherId + "]";
            writeChannelLog(fatherId, 241, result.equals(Constants.CODE_SUC) ? "创建成功"+streamAppendInfo : "创建失败"+streamAppendInfo);
            String code = liveStreamWebService.startDolby(fatherId, streamName);
            writeChannelLog(fatherId, 242, result.equals(Constants.CODE_SUC) ? "启动成功"+streamAppendInfo : "启动失败"+streamAppendInfo);
            return code;
        } catch (TException e) {
            logger.error("AutoDolby error", e);
        } catch (Exception e) {
            logger.error("AutoDolby error", e);
        }
        return Constants.CODE_ERROR;
    }

    public static String newTs(long fatherId, String streamName) {
        LiveStreamWebServiceImpl liveStreamWebService = (LiveStreamWebServiceImpl) ApplicationContextUtil.getBean(LiveStreamWebServiceImpl.class);

        try {
            liveStreamWebService.deleteNewTs(fatherId, streamName);
            String result = liveStreamWebService.createNewTs(fatherId, streamName);
            String streamAppendInfo= "[streamName=" + streamName + "][fatherId=" + fatherId + "]";
            writeChannelLog(fatherId, 251, result.equals(Constants.CODE_SUC) ? "创建成功"+streamAppendInfo : "创建失败"+streamAppendInfo);
            String code = liveStreamWebService.startNewTs(fatherId, streamName);
            writeChannelLog(fatherId, 252, result.equals(Constants.CODE_SUC) ? "启动成功"+streamAppendInfo : "启动失败"+streamAppendInfo);
            return code;
        } catch (TException e) {
            logger.error("AutoNewTs error", e);
        } catch (Exception e) {
            logger.error("AutoNewTs error", e);
        }

        return Constants.CODE_ERROR;
    }

    public static String p2p(long fatherId, String streamName, String streamIp) {
        LiveStreamWebServiceImpl liveStreamWebService = (LiveStreamWebServiceImpl) ApplicationContextUtil.getBean(LiveStreamWebServiceImpl.class);
        try {
            liveStreamWebService.p2pOffline(fatherId, streamName);
            String code = liveStreamWebService.p2pOnline(fatherId, streamName, streamIp);
            //记录操作日志
            ChannelService service = (ChannelService) ApplicationContextUtil.getBean(ChannelService.class);
            ChannelLog channelLog = new ChannelLog();
            channelLog.setFatherId(fatherId);
            channelLog.setUser("_system_");
            channelLog.setType(233);
            channelLog.setDescr(code);
            service.saveLog(channelLog);
            return code;
        } catch (TException e) {
            logger.error("AutoP2p error", e);
        } catch (Exception e) {
            logger.error("AutoP2p error", e);
        }
        return Constants.CODE_ERROR;
    }

    public static String auto(long fatherId, String streamName, String streamIp, boolean isEnabled, int streamApiVersion, boolean needDolby) {
        logger.info("[LiveStreamManager][auto][fatherId={}][streamName={}][streamIp={}][isEnabled={}]",
                fatherId, streamName, streamIp, isEnabled);
        String code = null;
        boolean hasFLV = false;
        boolean hasTS = false;
        boolean hasDOLBY = false;

        writeChannelLog(fatherId, 234, "操作成功 [streamName=" + streamName + "][streamIp=" + streamIp + "]");

        LiveStreamService liveStreamService = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
        LiveChannelStreamService liveChannelStreamService = (LiveChannelStreamService) ApplicationContextUtil.getBean(LiveChannelStreamService.class);
        QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
        ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);

        // Get LiveChannelStream
        LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

        if(null == liveChannelStream) {
            logger.error("[auto][fatherId={}][streamName={}] fail to get liveChannelStream", fatherId, streamName);
        }

        List<LiveStream> liveStreams = liveStreamService.get(fatherId, streamName);

        long qipuId = channelService.getQipuId(fatherId);
        if (liveStreams != null && liveStreams.size() > 0) {
            for (LiveStream liveStream : liveStreams) {
                if (liveStream.getStatus() == LiveStream.STATUS_STOP) {
                    liveStream.setStatus(LiveStream.STATUS_START);
                    liveStreamService.edit(liveStream);
                }

                if (isEnabled) { // 是否同步奇谱
                    qipuManager.addLiveStreamToQipu(qipuId, liveStream);
                }

                if (liveStream.getStatus() == LiveStream.STATUS_START || liveStream.getStatus() == LiveStream.STATUS_STOP) {
                    switch (liveStream.getFormatType()) {
                        case LiveStream.FORMATTYPE_FLV:
                            try {
                                JSONObject flvResult = restartFlv(liveStream.getUrl(), streamIp, streamName, streamApiVersion, liveChannelStream.getStreamUrls());
                                if (null != flvResult && "1".equals(flvResult.getString("status"))) {
                                    writeChannelLog(fatherId, 215, "重启成功 [streamName=" + streamName + "][url=" + liveStream.getUrl() + "][streamUrls="+liveChannelStream.getStreamUrls()+"]");
                                } else {
                                    writeChannelLog(fatherId, 215, "重启失败 [streamName=" + streamName + "][url=" + liveStream.getUrl()+ "][streamUrls="+liveChannelStream.getStreamUrls()+"]");
                                }
                            } catch (Exception e) {
                                writeChannelLog(fatherId, 215, "重启失败 [streamName=" + streamName + "][url=" + liveStream.getUrl() + "]");
                            }

                            // reset default live stream
                            if (liveStream.getIsDefault() && isEnabled) {
                                qipuManager.setDefaultLiveStreamToQipu(qipuId, liveStream);
                            }

                            hasFLV = true;
                            break;
                        case LiveStream.FORMATTYPE_TS:
                            try {
                                JSONObject tsResult = restartTs(liveStream.getUrl(), streamIp, streamName, streamApiVersion, liveChannelStream.getStreamUrls());

                                if (null != tsResult && "1".equals(tsResult.getString("status"))) {
                                    writeChannelLog(fatherId, 225, "重启成功 [streamName=" + streamName + "][url=" + liveStream.getUrl() + "][streamUrls="+liveChannelStream.getStreamUrls()+"]");
                                } else {
                                    writeChannelLog(fatherId, 225, "重启失败 [streamName=" + streamName + "][url=" + liveStream.getUrl() + "][streamUrls="+liveChannelStream.getStreamUrls()+"]");
                                }
                            } catch (Exception e) {
                                writeChannelLog(fatherId, 225, "重启失败 [streamName=" + streamName + "][url=" + liveStream.getUrl() +"]");
                            }
                            hasTS = true;
                            break;
                        case LiveStream.FORMATTYPE_DOLBY:
                            try {
                                JSONObject dolbyResult = restartDolby(liveStream.getDolby_ch(), null, streamApiVersion, liveChannelStream.getDolbyStreamUrls());

                                if (null != dolbyResult && "1".equals(dolbyResult.getString("status"))) {
                                    writeChannelLog(fatherId, 245, "重启成功 [streamName=" + streamName + "][url=" + liveStream.getDolby_ch() + "][streamUrls="+liveChannelStream.getDolbyStreamUrls()+"]");
                                } else {
                                    writeChannelLog(fatherId, 245, "重启失败 [streamName=" + streamName + "][url=" + liveStream.getDolby_ch() + "][streamUrls="+liveChannelStream.getDolbyStreamUrls()+"]");
                                }
                            } catch (Exception e) {
                                writeChannelLog(fatherId, 245, "重启失败 [streamName=" + streamName + "][url=" + liveStream.getDolby_ch() +"]");
                            }
                            hasDOLBY = true;
                            break;
                    }
                }
            }
        }

        if (hasFLV && !hasTS) {
            logger.info("[LiveStreamManager][auto]['FLV' restart, 'TS' create and start]");
            code = ts(fatherId, streamName, streamIp);
            if (!code.equals(Constants.CODE_SUC)) {
                return code;
            }
        } else if (!hasFLV && hasTS) {
            logger.info("[LiveStreamManager][auto]['TS' restart, 'FLV' create and start]");
            code = flv(fatherId, streamName, isEnabled ? "1" : "0", streamIp);
            if (!code.equals(Constants.CODE_SUC)) {
                return code;
            }
        } else if (!hasFLV && !hasTS) {
            logger.info("[LiveStreamManager][auto]['FLV' create and start, 'TS' create and start]");
            code = flv(fatherId, streamName, isEnabled ? "1" : "0", streamIp);
            if (!code.equals(Constants.CODE_SUC)) {
                return code;
            }
            code = ts(fatherId, streamName, streamIp);
            if (!code.equals(Constants.CODE_SUC)) {
                return code;
            }
//            code = p2p(fatherId, streamName, streamIp);
//            if (!code.equals(Constants.CODE_SUC)) {
//                return code;
//            }
        } else {
            logger.info("[LiveStreamManager][auto]['FLV' restart, 'TS' restart]");
            code = Constants.CODE_SUC;
        }

        if (!hasDOLBY && needDolby) {
            logger.info("[LiveStreamManager][auto]['DOLBY create and start]");
            code = dolby(fatherId, streamName);
//            if(!code.equals(Constants.CODE_SUC)) {
//                return code;
//            }
        }

        return code;
    }

    /**
     * 停止流下面的hcdn、ts、mp4、flv
     *
     * @param fatherId
     * @param streamName
     * @return
     */
    public static void stopAll(long fatherId, String streamName) {
        logger.info("[LiveStreamManager][stopAll][fatherId={}][streamName={}]", fatherId, streamName);

        LiveStreamWebServiceImpl liveStreamWebService = (LiveStreamWebServiceImpl) ApplicationContextUtil.getBean(LiveStreamWebServiceImpl.class);

        try {
            String flvResult = liveStreamWebService.stopFlv(fatherId, streamName, false);
            logger.info("[LiveStreamManager][stopAll][stopFlv][code={}]", flvResult);

            if (Constants.CODE_SUC.equals(flvResult)) {
                writeChannelLog(fatherId, 212, "操作成功 [streamName=" + streamName + "]");
            } else if (Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM.equals(flvResult)) {
                writeChannelLog(fatherId, 212, "操作失败,当前频道有正在直播的节目 [streamName=" + streamName + "]");
            }

            String tsResult = liveStreamWebService.stopTs(fatherId, streamName, false);
            logger.info("[LiveStreamManager][stopAll][stopTs][code={}]", tsResult);

            if (Constants.CODE_SUC.equals(tsResult)) {
                writeChannelLog(fatherId, 222, "操作成功 [streamName=" + streamName + "]");
            } else if (Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM.equals(tsResult)) {
                writeChannelLog(fatherId, 222, "操作失败,当前频道有正在直播的节目 [streamName=" + streamName + "]");
            }

            String dolbyResult = liveStreamWebService.stopDolby(fatherId, streamName, false);
            logger.info("[LiveStreamManager][stopAll][stopDolby][code={}]", dolbyResult);

            if (Constants.CODE_SUC.equals(dolbyResult)) {
                writeChannelLog(fatherId, 243, "操作成功 [streamName=" + streamName + "]");
            } else if (Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM.equals(dolbyResult)) {
                writeChannelLog(fatherId, 243, "操作失败,当前频道有正在直播的节目 [streamName=" + streamName + "]");
            }

//            if (Constants.CODE_SUC.equals(flvResult) && Constants.CODE_SUC.equals(tsResult)) {
//                writeChannelLog(fatherId, 235, "操作成功 [streamName=" + streamName + "]");
//            }else{
//                writeChannelLog(fatherId, 235, "操作失败 [streamName=" + streamName + "]");
//            }
        } catch (Exception e) {
            logger.info("[LiveStreamManager][stopAll][failed]");
            writeChannelLog(fatherId, 235, "操作失败 [streamName=" + streamName + "]");
        }
    }

    public static void writeChannelLog(long channelId, int type, String descr) {
        try {
            ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
            ChannelLog tChannelLog = new ChannelLog();
            tChannelLog.setFatherId(channelId);
            tChannelLog.setType(type);

            tChannelLog.setUser("system");
            tChannelLog.setDescr(descr);
            channelService.saveLog(tChannelLog);
        } catch (Exception e) {
            logger.info("[LiveStreamManager][writeChannelLog][exception=][channelId={}][type={}][desc={}]", e, channelId, type, descr);
        }
    }
}
